#from OpenTonitruum.Controller.Environment import Environment
#from Environment import Environment
from OpenTonitruum.Base.DataStructure import Event, Struct
from threading import Thread

class ParameterItem(object):
	def __init__(self, obj, description, member, defaultValue, fromPersistent = str, toPersistent = str):
		self.obj = obj
		self.description = description
		self.member = member
		self.defaultValue = defaultValue
		self.toPersistent = toPersistent
		self.fromPersistent = fromPersistent
		self.id = self.obj.__class__.__name__ + "." + member
		#self.value = defaultValue
		self.set(defaultValue)
	
	def get(self):
		return self.toPersistent(self.value)
		
	def set(self, value):
		#self.value = (value if isPersistentType else self.fromValue(value))
		self.value = value
		self.setInObject(value)
	
	def setInObject(self, strvalue):
		cobj = self.obj
		submembers = self.member.split(".")
		for submember in submembers[:-1]:
			if not hasattr(cobj, submember):
				setattr(cobj, submember, Struct())
			cobj = getattr(cobj, submember)
			#if cobj_ is None:
				#setattr(cobj, submember, Struct(nullable = True))
		setattr(cobj, submembers[-1], self.fromPersistent(strvalue))

class ParameterListener(object):
	def __init__(self, obj, description, member, initialValue):
		self.obj = obj
		self.description = description
		self.member = member
		self.id = self.obj.__class__.__name__ + "." + member
		self.initialValue = initialValue
	
	def __call__(self, *args):
		self.initialValue(*args)
	
	def add(self, callback):
		self.initialValue.add(callback)
	
	def createListener(self):
		cobj = self.obj
		submembers = self.member.split(".")
		for submember in submembers[:-1]:
			if not hasattr(cobj, submember):
				setattr(cobj, submember, Struct())
			cobj = getattr(cobj, submember)
		setattr(cobj, submembers[-1], self.initialValue)
		
class ParameterManager(object):
	def __init__(self):
		self.objects = []
		self.params = {}
		self.listeners = {}
		self.addItem = Event()
	
	def add(self, obj):
		self.objects.append(obj)
		for param in obj.requiredParameters():
			if isinstance(param, ParameterListener):
				if param.id in self.listeners:
					raise Exception('Duplicate parameter')
				self.listeners[param.id] = param
			else:
				if param.id in self.params:
					raise Exception('Duplicate parameter')
				self.params[param.id] = param
				self.addItem(param)
	
	def setValue(self, name, value):
		if name not in self.params:
			raise Exception('Parameter inexistent')
		self.params[name].set(value)
	
	def getValue(self, name):
		if name not in self.params:
			raise Exception('Parameter inexistent')
		return self.params[name].get(value)
	
	def addListener(self, name, callback):
		if name not in self.listeners:
			raise Exception('Parameter inexistent')
		self.listeners[name].add(callback)
	

class ParameterException(Exception):
	def __init__(self, message):
		self.message = message
		#self.message = parameter.description + ": " + message
		#self.parameter = parameter
		Exception.__init__(self)





